import axios, { type AxiosResponse, type AxiosError } from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useUserStore } from '@/stores/user'

// 创建axios实例
const request = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000',
    timeout: 30000,
})

// 请求拦截器
request.interceptors.request.use(
    (config) => {
        const userStore = useUserStore()

        // 添加access token到请求头
        if (userStore.accessToken) {
            config.headers.Authorization = `Bearer ${userStore.accessToken}`
        }

        return config
    },
    (error) => {
        return Promise.reject(error)
    }
)

// 刷新token的函数
let isRefreshing = false
let failedQueue: any[] = []

const processQueue = (error: any, token: string | null = null) => {
    failedQueue.forEach(prom => {
        if (error) {
            prom.reject(error)
        } else {
            prom.resolve(token)
        }
    })

    failedQueue = []
}

const refreshTokenRequest = async () => {
    const userStore = useUserStore()

    try {
        const response = await axios.post(`${request.defaults.baseURL}/jjx/refresh-token`, {
            refreshToken: userStore.refreshToken
        })

        if (response.data.success) {
            userStore.setTokens(response.data.data.accessToken, response.data.data.refreshToken)
            return response.data.data.accessToken
        } else {
            throw new Error('Token刷新失败')
        }
    } catch (error) {
        userStore.logout()
        window.location.href = '/login'
        throw error
    }
}

// 响应拦截器
request.interceptors.response.use(
    (response: AxiosResponse) => {
        // 后端返回的格式是 { success: boolean, message: string, data?: any }
        const { success, message, data } = response.data

        // 请求成功
        if (success) {
            return response.data
        }

        // 业务错误
        ElMessage.error(message || '请求失败')
        return Promise.reject(new Error(message || '请求失败'))
    },
    (error: AxiosError) => {
        const { response } = error

        if (response) {
            const { status, data } = response

            switch (status) {
                case 401:
                    // 如果当前在登录页面，直接显示错误信息（登录失败）
                    if (window.location.pathname === '/login' || window.location.pathname.includes('login')) {
                        ElMessage.error((data as any)?.message || '用户名或密码错误')
                        return Promise.reject(error)
                    }

                    // 其他页面的401错误，尝试刷新token
                    const originalRequest = error.config

                    if (!isRefreshing) {
                        isRefreshing = true

                        return refreshTokenRequest()
                            .then((newToken) => {
                                isRefreshing = false
                                processQueue(null, newToken)

                                // 重试原始请求
                                originalRequest.headers.Authorization = `Bearer ${newToken}`
                                return request(originalRequest)
                            })
                            .catch((refreshError) => {
                                isRefreshing = false
                                processQueue(refreshError, null)

                                // 刷新失败，跳转登录页
                                ElMessageBox.alert('登录已过期，请重新登录', '提示', {
                                    confirmButtonText: '重新登录',
                                    callback: () => {
                                        window.location.href = '/login'
                                    }
                                })
                                return Promise.reject(refreshError)
                            })
                    }

                    // 如果正在刷新，将请求加入队列
                    return new Promise((resolve, reject) => {
                        failedQueue.push({ resolve, reject })
                    }).then((token) => {
                        originalRequest.headers.Authorization = `Bearer ${token}`
                        return request(originalRequest)
                    }).catch((err) => {
                        return Promise.reject(err)
                    })
                    break
                case 403:
                    ElMessage.error('没有权限访问该资源')
                    break
                case 404:
                    ElMessage.error('请求的资源不存在')
                    break
                case 500:
                    ElMessage.error('服务器内部错误')
                    break
                default:
                    ElMessage.error((data as any)?.message || '网络错误')
            }
        } else {
            ElMessage.error('网络连接失败')
        }

        return Promise.reject(error)
    }
)

export default request